//
//  ExtensionFile.swift
//  RunTimeDemo
//
//  Created by YYPan on 2018/5/23.
//  Copyright © 2018年 YYPan. All rights reserved.
//

import UIKit

extension UIButton {
	
	/* 更改按钮的点击区域 */
	
	private struct RunTimeButtonKey {
		static let topEdgeKey = UnsafeRawPointer.init(bitPattern: "topEdgeKey".hashValue)
		static let rightEdgeKey = UnsafeRawPointer.init(bitPattern: "rightEdgeKey".hashValue)
		static let bottomEdgeKey = UnsafeRawPointer.init(bitPattern: "bottomEdgeKey".hashValue)
		static let leftEdgeKey = UnsafeRawPointer.init(bitPattern: "leftEdgeKey".hashValue)
	}
	
	private var topEdge: CGFloat? {
		set {
			objc_setAssociatedObject(self, RunTimeButtonKey.topEdgeKey!, newValue, .OBJC_ASSOCIATION_ASSIGN)
		}
		get {
			return objc_getAssociatedObject(self, RunTimeButtonKey.topEdgeKey!) as? CGFloat
		}
	}
	
	private var rightEdge: CGFloat? {
		set {
			objc_setAssociatedObject(self, RunTimeButtonKey.rightEdgeKey!, newValue, .OBJC_ASSOCIATION_ASSIGN)
		}
		get {
			return objc_getAssociatedObject(self, RunTimeButtonKey.rightEdgeKey!) as? CGFloat
		}
	}
	
	private var bottomEdge: CGFloat? {
		set {
			objc_setAssociatedObject(self, RunTimeButtonKey.bottomEdgeKey!, newValue, .OBJC_ASSOCIATION_ASSIGN)
		}
		get {
			return objc_getAssociatedObject(self, RunTimeButtonKey.bottomEdgeKey!) as? CGFloat
		}
	}
	
	private var leftEdge: CGFloat? {
		set {
			objc_setAssociatedObject(self, RunTimeButtonKey.leftEdgeKey!, newValue, .OBJC_ASSOCIATION_ASSIGN)
		}
		get {
			return objc_getAssociatedObject(self, RunTimeButtonKey.leftEdgeKey!) as? CGFloat
		}
	}
	
	func setEdge(top: CGFloat?, right: CGFloat?, bottom: CGFloat?, left: CGFloat?) {
		self.topEdge = top
		self.rightEdge = right
		self.bottomEdge = bottom
		self.leftEdge = left
	}
	
	open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
		let top = topEdge ?? 0
		let right = rightEdge ?? 0
		let bottom = bottomEdge ?? 0
		let left = leftEdge ?? 0
		
		let rect = CGRect(x: bounds.origin.x - left, y: bounds.origin.y - top, width: bounds.size.width + left + right, height: bounds.size.height + top + bottom)
		return rect.contains(point) ? self : nil
	}
}

extension UITapGestureRecognizer: UIGestureRecognizerDelegate {
	
	/* 控制手势点击的响应时间间隔 */
	
	private struct RunTimeTapKey {
		static let tapGestureDurationKey = UnsafeRawPointer.init(bitPattern: "tapGestureDuration".hashValue)
	}
	
	private var tapDuration: TimeInterval? {
		set {
			objc_setAssociatedObject(self, RunTimeTapKey.tapGestureDurationKey!, newValue, .OBJC_ASSOCIATION_ASSIGN)
		}
		get {
			return objc_getAssociatedObject(self, RunTimeTapKey.tapGestureDurationKey!) as? TimeInterval
		}
	}
	
	convenience init(target: Any?, action: Selector?, duration: TimeInterval?) {
		self.init(target: target, action: action)
		tapDuration = duration
		delegate = self
	}
	
	public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
		isEnabled = false
		let time = tapDuration ?? 0.0
		DispatchQueue.main.asyncAfter(deadline: .now() + time) {
			self.isEnabled = true
		}
		return true
	}
}
